home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmbase-grok-1.2 / convert.c < prev    next >
C/C++ Source or Header  |  1995-06-25  |  7KB  |  277 lines

  1. /*
  2.  * Convert date and time data formats.
  3.  *
  4.  *    mkdatestring(time)        Convert # of seconds since 1/1/70
  5.  *                    to a date string
  6.  *    mktimestring(time, dur)        Convert # of seconds since 1/1/70
  7.  *                    to a time-of-day or duration string
  8.  *    parse_datestring(text)        Interpret the date string, and
  9.  *                    return the # of seconds since 1/1/70
  10.  *    parse_timestring(text)        Interpret the time string, and
  11.  *                    return the # of seconds since 1/1/70
  12.  */
  13.  
  14.  
  15. #include "config.h"
  16. #include <X11/Xos.h>
  17. #include <stdio.h>
  18. #include <time.h>
  19. #include <X11/StringDefs.h>
  20. #include <Xm/Xm.h>
  21. #include "grok.h"
  22. #include "form.h"
  23. #include "proto.h"
  24.  
  25. extern struct pref    pref;        /* global configuration data */
  26.  
  27. char *weekday_name[7] =        { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
  28. char *alt_weekday_name[7] = { "Mo",  "Di",  "Mi",  "Do",  "Fr",  "Sa",  "So" };
  29.  
  30.  
  31. /*
  32.  * return some sensible string representation of a date (no time)
  33.  */
  34.  
  35. char *mkdatestring(
  36.     time_t            time)        /* date in seconds */
  37. {
  38.     static char        buf[40];    /* string representation */
  39.     struct tm        *tm;        /* time to m/d/y conv */
  40.  
  41.     tm = localtime(&time);
  42.     if (pref.mmddyy)
  43.         sprintf(buf, "%2d/%02d/%02d", tm->tm_mon+1, tm->tm_mday,
  44.                           tm->tm_year % 100);
  45.     else
  46.         sprintf(buf, "%2d.%02d.%02d", tm->tm_mday, tm->tm_mon+1,
  47.                           tm->tm_year % 100);
  48.     return(buf);
  49. }
  50.  
  51.  
  52. /*
  53.  * return some sensible string representation of a time (no date)
  54.  */
  55.  
  56. char *mktimestring(
  57.     time_t            time,        /* date in seconds */
  58.     BOOL            dur)        /* duration, not time-of-day */
  59. {
  60.     static char        buf[40];    /* string representation */
  61.     struct tm        *tm, tmbuf;    /* time to m/d/y conv */
  62.  
  63.     if (dur) {
  64.         tm = &tmbuf;
  65.         tm->tm_hour =  time / 3600;
  66.         tm->tm_min  = (time / 60) % 60;
  67.     } else
  68.         tm = localtime(&time);
  69.     if (pref.ampm && !dur)
  70.         sprintf(buf, "%2d:%02d%c", tm->tm_hour%12 ? tm->tm_hour%12 :12,
  71.                        tm->tm_min,
  72.                        tm->tm_hour < 12 ? 'a' : 'p');
  73.     else
  74.         sprintf(buf, "%02d:%02d",  tm->tm_hour, tm->tm_min);
  75.     return(buf);
  76. }
  77.  
  78.  
  79. /*
  80.  * parse the date string, and return the number of seconds. The default
  81.  * time argument is for the +x notation, it's typically the trigger date
  82.  * of the appointment. Use 0 if it's not available; today is default.
  83.  * Doesn't know about alpha month names yet. The time on the recognized
  84.  * date is set to 0:00.
  85.  */
  86.  
  87. time_t parse_datestring(
  88.     char        *text)        /* input string */
  89. {
  90.     time_t        today;        /* current date in seconds */
  91.     struct tm    *tm;        /* today's date */
  92.     long        num[3];        /* m,d,y or d,m,y */
  93.     int        nnum;        /* how many numbers in text */
  94.     long        i;        /* tmp counter */
  95.     char        *p;        /* text scan pointer */
  96.     char        buf[10];    /* lowercase weekday name */
  97.     BOOL        mmddyy = pref.mmddyy;
  98.  
  99.     today = time(0);                /* today's date */
  100.     tm = localtime(&today);
  101.     tm->tm_hour = tm->tm_min = tm->tm_sec = 0;
  102.     tm->tm_hour = 12;
  103.     while (*text == ' ' || *text == '\t')        /* skip blanks */
  104.         text++;
  105.     for (p=text; *p; p++)                /* -> lowercase */
  106.         if (*p >= 'A' && *p <= 'Z')
  107.             *p += 'a' - 'A';
  108.                             /* today, tomorrow? */
  109.     if (!strncmp(text, "tod", 3) ||
  110.         !strncmp(text, "heu", 3) ||
  111.         !strncmp(text, "auj", 3) || !*text)
  112.         return(today);
  113.  
  114.     if (!strncmp(text, "tom", 3) ||
  115.         !strncmp(text, "mor", 3) ||
  116.         !strncmp(text, "dem", 3))
  117.         return(today + 86400);
  118.  
  119.     if (!strncmp(text, "yes", 3) ||
  120.         !strncmp(text, "ges", 3) ||
  121.         !strncmp(text, "hie", 3))
  122.         return(today - 86400);
  123.  
  124.     if (!strncmp(text, "ueb", 3))
  125.         return(today + 2*86400);
  126.                             /* weekday name? */
  127.     for (i=0; i < 7; i++) {
  128.         strcpy(buf, weekday_name[i]);
  129.         *buf += 'a' - 'A';
  130.         if (!strncmp(buf, text, strlen(buf)))
  131.             break;
  132.         strcpy(buf, alt_weekday_name[i]);
  133.         *buf += 'a' - 'A';
  134.         if (!strncmp(buf, text, strlen(buf)))
  135.             break;
  136.     }
  137.     if (i < 7) {
  138.         i = (i - tm->tm_wday + 8) % 7;
  139.         return(today + i*86400);
  140.     }
  141.                             /* d/m/y numbers? */
  142.     num[0] = num[1] = num[2] = 0;
  143.     p = text;
  144.     for (nnum=0; nnum < 3; nnum++) {
  145.         while (*p >= '0' && *p <= '9')
  146.             num[nnum] = num[nnum]*10 + *p++ - '0';
  147.         while (*p && !(*p >= '0' && *p <= '9')) {
  148.             if (*p == '.')
  149.                 mmddyy = FALSE;
  150.             if (*p == '/')
  151.                 mmddyy = TRUE;
  152.             p++;
  153.         }
  154.     }
  155.     if (nnum == 0)                    /* ... no numbers */
  156.         return(today);
  157.     if (nnum == 3) {                /* ... have year? */
  158.         if (num[2] < 70)
  159.             num[2] += 100;
  160.         if (num[2] > 99)
  161.             num[2] -= 1900;
  162.         if (num[2] < 70 || num[2] > 170)
  163.             num[2]  = tm->tm_year;
  164.         tm->tm_year = num[2];
  165.     }
  166.     if (nnum == 1) {                /* ... day only */
  167.         if (num[0] < tm->tm_mday)
  168.             if (++tm->tm_mon == 12) {
  169.                 tm->tm_mon = 0;
  170.                 tm->tm_year++;
  171.             }
  172.         tm->tm_mday = num[0];
  173.     } else {                    /* ... d.m or m/d */
  174.         if (mmddyy) {
  175.             i      = num[0];
  176.             num[0] = num[1];
  177.             num[1] = i;
  178.         }
  179.         if (nnum < 3 && num[1]*100+num[0] <
  180.                         (tm->tm_mon+1)*100+tm->tm_mday)
  181.             tm->tm_year++;
  182.         tm->tm_mday = num[0];
  183.         tm->tm_mon  = num[1]-1;
  184.     }
  185.     return(mktime(tm));
  186. }
  187.  
  188.  
  189. /*
  190.  * parse the time string, and return the number of seconds since midnight.
  191.  * The time returned is in Unix format, in seconds since 1/1/1970. In
  192.  * particular, midnight is not necessarily 0, depending on the time zone.
  193.  */
  194.  
  195. time_t parse_timestring(
  196.     char            *text,        /* input string */
  197.     BOOL            dur)        /* duration, not time-of-day */
  198. {
  199.     time_t            today;        /* current date in seconds */
  200.     struct tm        *tm;        /* m/d/y to time conv */
  201.     long            num[3];        /* h,m,s */
  202.     int            nnum;        /* how many numbers in text */
  203.     int            ndigits;    /* digit counter */
  204.     char            *p = text;    /* text pointer */
  205.     int            i;        /* text index, backwards*/
  206.     char            ampm = 0;    /* 0, 'a', or 'p' */
  207.     int            h, m, s;    /* hours, minutes, seconds */
  208.  
  209.     while (*p == ' ' || *p == '\t')
  210.         p++;
  211.     i = strlen(p)-1;
  212.     while (i && (p[i] == ' ' || p[i] == '\t'))
  213.         i--;
  214.     if (i && p[i] == 'm')
  215.         i--;
  216.     if (i && (p[i] == 'a' || p[i] == 'p'))
  217.         ampm = p[i--];
  218.     while (i && (p[i] == ' ' || p[i] == '\t'))
  219.         i--;
  220.     num[0] = num[1] = num[2] = 0;
  221.     for (nnum=0; i >= 0 && nnum < 3; nnum++) {
  222.         ndigits = 0;
  223.         while (i >= 0 && (p[i] < '0' || p[i] > '9'))
  224.             i--;
  225.         while (i >= 0 && p[i] >= '0' && p[i] <= '9' && ndigits++ < 2)
  226.             num[nnum] += (p[i--] - '0') * (ndigits==1 ? 1 : 10);
  227.     }
  228.     if (ampm && nnum == 1) {
  229.         nnum = 2;
  230.         num[1] = num[0];
  231.         num[0] = 0;
  232.     }
  233.     switch(nnum) {
  234.       case 0:    h = 0;        m = 0;        s = 0;        break;
  235.       case 1:    h = 0;        m = num[0];    s = 0;        break;
  236.       case 2:    h = num[1];    m = num[0];    s = 0;        break;
  237.       case 3:    h = num[2];    m = num[1];    s = num[0];    break;
  238.     }
  239.     if (pref.ampm) {
  240.         if (ampm == 'a' && h == 12)
  241.             h = 0;
  242.         if (ampm == 'p' && h < 12)
  243.             h += 12;
  244.     }
  245.     today = time(0);
  246.     tm = localtime(&today);
  247.     tm->tm_hour = h;
  248.     tm->tm_min  = m;
  249.     tm->tm_sec  = s;
  250.     return(dur ? 3600*h + 60*m + s : mktime(tm));
  251. }
  252.  
  253.  
  254. /*
  255.  * parse string with both date and time
  256.  */
  257.  
  258. time_t parse_datetimestring(
  259.     char            *text)        /* input string */
  260. {
  261.     struct tm    tm1, tm2;    /* for adding date and time */
  262.     time_t        t;        /* parsed time */
  263.  
  264.     t = parse_datestring(text);
  265.     tm1 = *localtime(&t);
  266.     while (*text && *text != ' ' && *text != '\t')
  267.         text++;
  268.     while (*text == ' ' || *text == '\t')
  269.         text++;
  270.     t = parse_timestring(text, FALSE);
  271.     tm2 = *localtime(&t);
  272.     tm1.tm_hour = tm2.tm_hour;
  273.     tm1.tm_min  = tm2.tm_min;
  274.     tm1.tm_sec  = tm2.tm_sec;
  275.     return(mktime(&tm1));
  276. }
  277.